package com.yxp423.ssmempl.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

import java.lang.reflect.Method;
import java.nio.charset.Charset;


/**
 * @Description: java类作用描述
 * @Author: yxp
 * @CreateDate: 2019-06-02 15:05
 * @Version: 1.0
 */
@Configuration
@EnableCaching
@EnableAutoConfiguration

public class RedisConfig extends CachingConfigurerSupport {


	@Bean
	public KeyGenerator wiselyKeyGenerator(){
		return new KeyGenerator() {
			@Override
			public Object generate(Object target, Method method, Object... params) {
				StringBuilder sb = new StringBuilder();
				sb.append(target.getClass().getName());
				sb.append(method.getName());
				for (Object obj : params) {
					sb.append(obj.toString());
				}
				return sb.toString();
			}
		};

	}


	@Bean
	public CacheManager cacheManager(
			@SuppressWarnings("rawtypes") RedisTemplate redisTemplate) {
		return new RedisCacheManager(redisTemplate);
	}

	@Bean
	public RedisTemplate<String, String> redisTemplate(
			RedisConnectionFactory factory) {
		StringRedisTemplate template = new StringRedisTemplate(factory);
		FastJsonRedisSerializer<Object> serializer = new FastJsonRedisSerializer<>(Object.class);

		template.setValueSerializer(serializer);
		template.afterPropertiesSet();
		return template;
	}



	private static class FastJsonRedisSerializer<T> implements RedisSerializer<T> {

		private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

		private final static ParserConfig defaultRedisConfig = new ParserConfig();
		static { defaultRedisConfig.setAutoTypeSupport(true);}

		private Class<T> clazz;

		public FastJsonRedisSerializer(Class<T> clazz) {
			this.clazz = clazz;
		}

		@Override
		public byte[] serialize(T t) throws SerializationException {
			if (t == null) {
				return new byte[0];
			}
			return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
		}

		@Override
		public T deserialize(byte[] bytes) throws SerializationException {
			if (bytes == null || bytes.length <= 0) {
				return null;
			}
			String str = new String(bytes, DEFAULT_CHARSET);
			return (T) JSON.parseObject(str, clazz);
		}
	}

}
